﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSF.Security.Data;

namespace CSF.Security.BLL
{
    /// <summary>
    /// 权限树数据类型
    /// </summary>
    public class PermissionTree
    {
        /// <summary>
        /// 路径path和权限的字典，用于快速查找
        /// </summary>
        public Dictionary<string, PermissionTreeNode> _map = new Dictionary<string, PermissionTreeNode>();

        public PermissionTreeNode _root = new PermissionTreeNode(null);

        /// <summary>
        /// 查找与某个路径对应的节点
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public PermissionTreeNode Find(string path)
        {
            PermissionTreeNode result = null;
            path = path.ToLower();
            if (_map.ContainsKey(path))
            {
                result = _map[path];
            }
            else
            {
                foreach (var node in _root.Children)
                {
                    result = Find(path, node);
                    if (result != null || path.CompareTo(node.Permission.Path) < 0)
                        break;
                }
            }
            return result;
        }

        public PermissionTreeNode Find(string path, PermissionTreeNode node)
        {
            PermissionTreeNode result = null;
            if (path.Equals(node.Permission.Path))
            {
                result = node;
            }
            else if (path.StartsWith(node.Permission.Path))
            {
                result = node;

                PermissionTreeNode newresult = null;
                foreach (var subnode in node.Children)
                {
                    newresult = Find(path, subnode);
                    if (newresult != null || path.CompareTo(subnode.Permission.Path) < 0)
                    {
                        result = newresult;
                        break;
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 创建用于权限查询的树结构
        /// </summary>
        /// <param name="permissions"></param>
        /// <param name="rolePermissions"></param>
        /// <returns></returns>
        public static PermissionTree Create(IEnumerable<Permission> permissions)
        {
            PermissionTree tree = new PermissionTree();

            List<Permission> tempList = (from p in permissions
                                         orderby p.Path
                                         select p).ToList();
            ILookup<int, Permission> subpermissions = tempList.ToLookup(p => p.ParentId ?? 0);
            int i = 0;

            tree.BuildTree(tree._root, 0, i, subpermissions);
            return tree;
        }

        /// <summary>
        /// 构造树节点
        /// </summary>
        /// <param name="node"></param>
        /// <param name="parentId"></param>
        /// <param name="i"></param>
        /// <param name="tempRoleList"></param>
        /// <param name="lookupSubPermission"></param>
        private void BuildTree(PermissionTreeNode node, int parentId, int i,
            ILookup<int, Permission> lookupSubPermission)
        {
            var subPermissions = lookupSubPermission[parentId];

            foreach (var permission in subPermissions)
            {
                permission.Path = permission.Path == null ? null : permission.Path.ToLower();

                var subNode = new PermissionTreeNode(permission);
                
                // 将树的节点放入字典中以便快速查找
                _map.Add(permission.Path, subNode);

                node.Children.Add(subNode);
                BuildTree(subNode, permission.Id, i, lookupSubPermission);
            }
        }
    }
}
